package thread;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: a
 * Date: 2022-10-07
 * Time: 16:11
 */

//实现阻塞队列
class MyBlockingQueue{
    //设数组最大存储1000个元素
    private int[] items = new int[1000];

    //设置队首队尾位置
    private int head = 0;
    private int tail = 0;

    //队列元素个数
    private volatile int size = 0;

    //入队列
    public void put(int value) throws InterruptedException {
        synchronized (this){
            while(size == items.length){
                //表示这时候队列已经满了, 需要进行阻塞等待
                this.wait();
            }
            items[tail] = value;
            tail++;
            if(tail == items.length){
                tail = 0;
            }
            size++;
            this.notify();
        }
    }

    //出队列
    public Integer take() throws InterruptedException {
        int res = 0;
        synchronized (this){
            while(size == 0){
                //表示这时候队列为空, 需要进行阻塞等待
                this.wait();
            }
            res = items[head];
            head++;
            if(head == items.length){
                head = 0;
            }
            size--;
            this.notify();
        }
        return res;
    }
}

public class Demo10 {
    //使用阻塞队列实现生产者消费者模型
    public static void main(String[] args) {
        //BlockingQueue<Integer> blockingQueue = new LinkedBlockingQueue<>();
        MyBlockingQueue blockingQueue = new MyBlockingQueue();
        Thread customer = new Thread(() -> {
            while(true){
                try {
                    int value = blockingQueue.take();
                    System.out.println("消费元素:" + value);
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        Thread producer = new Thread(() -> {
            int value = 0;
            while(true){
                try {
                    System.out.println("生产元素:" + value);
                    blockingQueue.put(value);
                    value++;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        customer.start();
        producer.start();
    }
}
